issubclass() や isinstance() を使ったインターフェースに対するテスト(collections.abc)
以下の3つのいずれかの方法で動作します。
1) A newly written class can inherit directly from one of the abstract base classes.
「新しく書かれたクラスは、抽象基底クラスの1つから直接継承して書ける」
class C(Sequence):
抽象メソッドを実装する
issubclass(C, Sequence)もisinstance(C(), Sequence)もTrue
2) Existing classes and built-in classes can be registered as "virtual subclasses" of the ABCs.
class D:(継承なし)
抽象メソッド(例:__getitem__)やMixinメソッド(例:count)を定義
Sequence.register(D)
issubclass(D, Sequence)もisinstance(D(), Sequence)もTrue
この例では、クラス D は __contains__, __iter__, __reversed__ を定義する必要がありません。
なぜなら in 演算子, the 反復 ロジック, および reversed() 関数は自動的に __getitem__ と __len__ を使うようにフォールバックするからです。
3) Some simple interfaces are directly recognizable by the presence of the required methods
code:third_example.py
class E:
def __iter__(self): ...
def __next__(next): ...
issubclass(E, Iterable)もisinstance(E(), Iterable)もTrue
複雑なインターフェースは、単に特定のメソッドが存在すること以上の定義を持つため、3番目のテクニックをサポートしていません。
たとえば、あるクラスが __getitem__, __len__, および __iter__ を提供するというだけでは、 Sequence と Mapping を区別するには不十分です。